
package fmu.pi.model.dao;

import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import fmu.pi.business.vo.MovimentacaoVO;
import fmu.pi.model.bean.Entidade;
import fmu.pi.model.bean.Movimentacao;
import fmu.pi.model.dao.old.Dao;
import fmu.pi.utils.Utils;


public class MovimentacaoDao extends Dao
{
    private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 
    
    
    
    
    public Map<Integer,MovimentacaoVO> obterMovimentacaoUltimoTrimestre() throws SQLException {
    	 
		final String qry = "SELECT MONTH(dataMovimentacao) as mes, SUM(valor) as valor "
				+ "FROM movimentacao WHERE MONTH(dataMovimentacao) IN (?, ?, ?) "
				+ "GROUP BY MONTH(dataMovimentacao) "
				+ "ORDER BY MONTH(dataMovimentacao) DESC;";

		PreparedStatement statement = getConnection().prepareStatement(qry);
		
		statement.setInt(1, Utils.mesAtual());
		statement.setInt(2, Utils.mesAtual() - 1);
		statement.setInt(3, Utils.mesAtual() - 2);
		
		ResultSet rs = statement.executeQuery(); 
		
		Map<Integer,MovimentacaoVO> mov = new HashMap<>();
		
		while(rs.next()) {
			mov.put(rs.getInt("MES"), new MovimentacaoVO(rs.getInt("MES"), rs.getBigDecimal("VALOR")));
		}
		
    	return mov;
    }
    
    
    public List<MovimentacaoVO> obterBalancoAnual(Integer ano) throws SQLException {
   	 
		final String qry = "SELECT MONTH(dataMovimentacao) as mes, SUM(valor) as valor "
				+ "FROM movimentacao WHERE YEAR(dataMovimentacao) = ? "
				+ "GROUP BY MONTH(dataMovimentacao) "
				+ "ORDER BY MONTH(dataMovimentacao); ";

		PreparedStatement statement = getConnection().prepareStatement(qry);
		
		statement.setInt(1, ano);
		
		ResultSet rs = statement.executeQuery(); 
		
		List<MovimentacaoVO> mov = new ArrayList<>();
		
		while(rs.next()) {
			mov.add(new MovimentacaoVO(rs.getInt("MES"), rs.getBigDecimal("VALOR")));
		}
		
    	return mov;
    }
    
    
    
    /////////////////////////////////////////////////////////////////
    
    public Integer insert(Entidade entidade)
    {
        PreparedStatement statement = null; 
        Movimentacao mov = (Movimentacao) entidade;
        Integer result = 0; 
        final String QUERY = "insert into movimentacao(cartao_idcartao, conta_idconta, sequencia, valor, observacao, datamovimentacao)"
                +"values(?, ?, ?, ?, ?, ?);";
        
        try
        {
            statement =  getConnection().prepareStatement(QUERY); 
            statement.setInt(1, mov.getIdCartao()); 
            statement.setInt(2, mov.getIdConta()); 
            statement.setInt(3, mov.getSequencia());
            statement.setFloat(4, mov.getValor()); 
            statement.setString(5, mov.getObservacao()); 
            java.util.Date data = dateFormat.parse(mov.getDataPagamento());
            statement.setDate(6, new Date(data.getTime()));
            result = statement.executeUpdate(); 
        }
        catch(SQLException exception)
        {
            System.err.println("Erro ao inserir movimentacao no banco de dados!"); 
            exception.printStackTrace(); 
        }
        catch(ParseException exception)
        {
            System.err.println("Erro ao formatar data."); 
            exception.printStackTrace(); 
        }
        finally
        {
            try
            {
                if(statement != null )
                    statement.close(); 
            }
            catch(SQLException exception)
            {
                exception.printStackTrace(); 
            }
        }
        
        return result; 
    }
    
    public Integer update(Entidade entidade)
    {
        PreparedStatement statement = null; 
        Movimentacao mov = (Movimentacao) entidade; 
        Integer result = 0; 
        final String QUERY = "update movimentacao set cartao_idcartao = ?, conta_idconta = ?, sequencia = ?, valor = ?, observacao = ? , datamovimentacao = ? where idMovimentacao = " 
                + mov.getIdMovimentacao();
        
        try
        {
            statement =  getConnection().prepareStatement(QUERY); 
            statement.setInt(1, mov.getIdCartao()); 
            statement.setInt(2, mov.getIdConta()); 
            statement.setInt(3, mov.getSequencia()); 
            statement.setFloat(4, mov.getValor()); 
            statement.setString(5, mov.getObservacao());
            java.util.Date data = dateFormat.parse(mov.getDataPagamento()); 
            statement.setDate(6, new Date(data.getTime())); 
            result = statement.executeUpdate();  
        }
        catch(SQLException exception)
        {
            System.err.println("Erro ao alterar movimentacao no banco de dados!"); 
            exception.printStackTrace(); 
        }
        catch(ParseException exception)
        {
            System.err.println("Erro ao formatar data"); 
            exception.printStackTrace(); 
        }
        finally
        {
            try
            {
                if(statement != null )
                    statement.close(); 
            }
            catch(SQLException exception)
            {
                exception.printStackTrace(); 
            }
        }
        
        return result; 
    }
    
    public Integer delete(Entidade entidade)
    {
        PreparedStatement statement = null; 
        Movimentacao mov = (Movimentacao) entidade; 
        Integer result = 0; 
        final String QUERY = "delete from movimentacao where idmovimetacao = "
                +mov.getIdMovimentacao();
        
        try
        {
            statement =  getConnection().prepareStatement(QUERY); 
            result = statement.executeUpdate(); 
        }
        catch(SQLException exception)
        {
            System.err.println("Erro ao apagar movimentacção do banco de dados!"); 
            exception.printStackTrace(); 
        }
        finally
        {
            try
            {
                if(statement != null )
                    statement.close(); 
            }
            catch(SQLException exception)
            {
                exception.printStackTrace(); 
            }
        }
        
        return result; 
    }
    
    public List<Entidade> read()
    {
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        List<Entidade> movs = new ArrayList<Entidade>(); 
        final String QUERY = "select * from movimentacao order by datamovimentacao,"
                +"sequencia;";
        
        try
        {
            statement =  getConnection().prepareStatement(QUERY); 
            resultSet = statement.executeQuery(); 
            
            while(resultSet.next())
            {
                Movimentacao mov = new Movimentacao();
                mov.setIdMovimentacao(resultSet.getInt("idmovimentacao"));
                mov.setIdCartao(resultSet.getInt("CARTAO_idcartao")); 
                mov.setIdConta(resultSet.getInt("conta_idconta"));
                mov.setSequencia(resultSet.getInt("sequencia"));
                mov.setValor(resultSet.getFloat("valor")); 
                mov.setObservacao(resultSet.getString("observacao")); 
                mov.setDataPagamento(dateFormat.format(
                        resultSet.getDate("datamovimentacao")));
                movs.add(mov); 
            } 
        }
        catch(SQLException exception)
        {
            System.err.println("Erro ao recuperar movimentações do banco de dados!"); 
            exception.printStackTrace(); 
        }
        finally
        {
            try
            {
                if(statement != null ){
                    statement.close();
                    resultSet.close(); 
                }
            }
            catch(SQLException exception)
            {
                exception.printStackTrace(); 
            }
        }
        
        return movs;
    }
}
